package com.gitee.apanlh.util.encode;

import com.gitee.apanlh.exp.EncodeException;
import com.gitee.apanlh.util.reflection.ClassConvertUtils;
import com.gitee.apanlh.util.valid.ValidParam;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.Charset;

/**	
 * 	字符集编码
 * 	
 * 	@author Pan
 */
public class StrEncodeUtils {
	
	/**
	 * 	不允许外部示例
	 * 	@author Pan
	 */
	private StrEncodeUtils() {
		super();
	}
	
	/**	
	 * 	指定编码转换UTF-8
	 * 	
	 * 	@author Pan
	 * 	@param 	str		字符串
	 * 	@param 	charset	字符集
	 * 	@return	String
	 */
	public static String utf8EncodeToStr(String str, String charset) {
		try {
			return utf8EncodeToStr(str.getBytes(charset));
		} catch (UnsupportedEncodingException e) {
			throw new EncodeException(e.getMessage(), e);
		}
	}
	
	/**	
	 * 	byte转换String
	 * 	<br>指定字符集
	 * 
	 * 	@author Pan
	 * 	@param  bytes	字节数组
	 * 	@param  charset	字符集
	 * 	@return	String
	 */
	public static String utf8EncodeToStr(byte[] bytes, String charset) {
		try {
			return new String(bytes, charset);
		} catch (UnsupportedEncodingException e) {
			throw new EncodeException(e.getMessage(), e);
		}
	}
	
	/**	
	 * 	byte转换String
	 * 	<br>字符集UTF-8
	 * 
	 * 	@author Pan
	 * 	@param  bytes	字节数组
	 * 	@return	String
	 */
	public static String utf8EncodeToStr(byte[] bytes) {
		return utf8EncodeToStr(bytes, CharsetCode.UTF_8);
	}
	
	/**	
	 * 	将字符集转换为UTF-8
	 * 	
	 * 	@author Pan
	 * 	@param 	content	内容
	 * 	@return	String
	 */
	public static String utf8EncodeToStr(String content) {
		return utf8EncodeToStr(utf8EncodeToBytes(content));
	}
	
	/**	
	 * 	String转换byte
	 * 	<br>自定义编码
	 * 
	 * 	@author Pan
	 * 	@param  content	内容
	 * 	@param  charset	字符集
	 * 	@return	byte[]
	 */
	public static byte[] utf8EncodeToBytes(String content, String charset) {
		try {
			return content.getBytes(charset);
		} catch (UnsupportedEncodingException e) {
			throw new EncodeException(e.getMessage(), e);
		}
	}
	
	/**	
	 * 	String转换byte
	 * 	<br>自定义编码
	 * 
	 * 	@author Pan
	 * 	@param  content	内容
	 * 	@param	charset	字符编码
	 * 	@return	byte[]
	 */
	public static byte[] utf8EncodeToBytes(String content, Charset charset) {
		return content.getBytes(charset);
	}
	
	/**	
	 * 	String转换byte
	 * 	<br>字符集UTF-8
	 * 	
	 * 	@author Pan
	 * 	@param  content	内容
	 * 	@return	byte[]
	 */
	public static byte[] utf8EncodeToBytes(String content) {
		return utf8EncodeToBytes(content, CharsetCode.UTF_8);
	}
	
	/**	
	 * 	CharSequence转换byte
	 * 	<br>StringBuilder/StringBuffer等
	 * 	<br>字符集UTF-8
	 * 	
	 * 	@author Pan
	 * 	@param  content	内容
	 * 	@return	byte[]
	 */
	public static byte[] utf8EncodeToBytes(CharSequence content) {
		try {
			return content.toString().getBytes(CharsetCode.UTF_8);
		} catch (UnsupportedEncodingException e) {
			throw new EncodeException(e.getMessage(), e);
		}
	}
	
	/**	
	 * 	根据指定编码对字符串进行转码	
	 * 	<br>进行UTF-8转码
	 * 
	 * 	@author Pan
	 * 	@param  content	内容
	 * 	@return	String
	 */
	public static String urlEncode(String content) {
		return urlEncode(content, CharsetCode.UTF_8);
	}
	
	/**	
	 * 	根据指定编码对字符串进行转码
	 * 	
	 * 	@author Pan
	 * 	@param  content	内容
	 * 	@param  charset	字符集
	 * 	@return	String
	 */
	public static String urlEncode(String content, String charset) {
		try {
			return URLEncoder.encode(content, charset);
		} catch (UnsupportedEncodingException e) {
			throw new EncodeException(e.getMessage(), e);
		}
	}
	
	/**	
	 * 	对字符串解码
	 * 	<br>进行UTF-8解码
	 * 	
	 * 	@author Pan
	 * 	@param  content	内容
	 * 	@return	String
	 */
	public static String urlDecode(String content) {
		return urlDecode(content, CharsetCode.UTF_8);
	}
	
	/**	
	 * 	对字符串进行 解码
	 * 	
	 * 	@author Pan
	 * 	@param  content	内容
	 * 	@param  charset	字符集
	 * 	@return	String
	 */
	public static String urlDecode(String content, String charset) {
		try {
			return URLDecoder.decode(content, charset);
		} catch (UnsupportedEncodingException e) {
			throw new EncodeException(e.getMessage(), e);
		}
	}
	
	/**	
	 * 	String转换Unicode
	 *  
	 * 	@author Pan
	 * 	@param  content	内容
	 * 	@return	String
	 */
	public static String unicodeEncode(String content) {
		if (ValidParam.isEmpty(content)) {
			return content;
		}
		
		StringBuilder strBuilder = new StringBuilder((content.length() * 6) + 1);
		
		int index = 0;
		int len = content.length();
		while (index < len) {
			char c = content.charAt(index);
			strBuilder.append("\\u");
			if ((c >>> 8) == 0) {
				strBuilder.append("00");
			}
			strBuilder.append(HexUtils.encode(c));
			index++;
		}
		
		return strBuilder.toString();
	}
	
	/**	
	 * 	Unicode转换Str
	 * 	
	 * 	@author Pan
	 * 	@param  content	内容
	 * 	@return	String
	 */
	public static String unicodeDecode(String content) {
		if (ValidParam.isEmpty(content)) {
			return content;
		}
		
		int strLen = content.length();
		int index = 0;
		StringBuilder strBuilder = new StringBuilder((strLen / 6) + 1);
		
		while (index < strLen) {
			char c = content.charAt(index);
			if (c == '\\' && content.charAt(index + 1) == 'u') {
				strBuilder.append((char) ClassConvertUtils.toInt(content.substring(index + 2, index + 6), 16));
				index += 6;
			} else {
				strBuilder.append(c);
				index++;
			}
		}
		return strBuilder.toString();
	}
}
